﻿using System;

using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace Silvermoon.Controls
{
    /// <summary>
    /// EventArgs that provide information for Cancel and Handled.
    /// </summary>
    public class HandledEventArgs : EventArgs
    {
        public bool Handled { get; set; }

        /// <summary>
        /// Set to true to cancel following event args for other controls in the hierarchy.
        /// </summary>
        public bool Cancel { get; set; }
    }

    public class MouseEventArgs : HandledEventArgs
    {
        /// <summary>
        /// Gets the bounds of the control absolutely in the screen.
        /// </summary>
        public Rectangle ScreenBounds { get; internal set; }



        /// <summary>
        /// Converts a screen point to the client point.
        /// </summary>
        /// <param name="point">The point to convert.</param>
        /// <returns>The coordinates for the client.</returns>
        public Point ScreenToClient(Point point)
        {
            return new Point(point.X - ScreenBounds.Left, point.Y - ScreenBounds.Top);
        }

    }


    public class MouseDownEventArgs : MouseEventArgs
    {
        internal MouseDownEventArgs() : base() { }

        public MouseDownEventArgs(Point position)
            : base()
        {
            this.Position = position;
        }


        public Point Position { get; internal set; }
    }

    public enum MouseUpReason
    {
        ButtonUp = 1,
        BeginScroll = 2
    }


    public class MouseUpEventArgs : MouseEventArgs
    {
        internal MouseUpEventArgs() : base() { }

        public MouseUpEventArgs(Point downPos, Point upPos, int duration, int distance)
            : base()
        {
            DownPosition = downPos;
            UpPosition = upPos;
            Duration = duration;
            Distance = distance;
        }
        public MouseUpReason Reason { get; internal set; }
        public Point DownPosition { get; internal set; }
        public Point UpPosition { get; internal set; }
        public int Duration { get; internal set; }
        public int Distance { get; internal set; }

        /// <summary>
        /// Set to false to hint <see cref="MessageEngine"/> not to check for double clicks and thus do not delay a ClickEvent for a single click.
        /// </summary>
        public bool AllowDoubleClick { get; set; }

    }

    public class MouseMoveEventArgs : MouseEventArgs
    {
        /// <summary>
        /// Gets the position where mouse moving started.
        /// </summary>
        public Point StartPosition { get; internal set; }

        /// <summary>
        /// Gets the current mouse position.
        /// </summary>
        public Point Position { get; internal set; }


        public Point GetDeltaPos()
        {
            return new Point(Position.X - StartPosition.X, Position.Y - StartPosition.Y);
        }

        public Point GetAbsDeltaPos()
        {
            return new Point(Math.Abs(Position.X - StartPosition.X), Math.Abs(Position.Y - StartPosition.Y));
        }

        public int Dx { get { return Position.X - StartPosition.X; } }
        public int Dy { get { return Position.Y - StartPosition.Y; } }
        public int Ax { get { return Math.Abs(Dx); } }
        public int Ay { get { return Math.Abs(Dy); } }

    }

    /// <summary>
    /// Same as MouseMoveEventArgs but occurs even if the mouse is actually not pressed due to simulated accelleration.
    /// </summary>
    public class ScrollEventArgs : MouseMoveEventArgs
    {
        public bool IsMouseDown { get; internal set; }
    }

    /// <summary>
    /// Occurs befor sending intervalls of ScrollEventArgs.
    /// </summary>
    public class BeginScrollEventArgs : MouseMoveEventArgs
    {
        /// <summary>
        /// Gets or sets the duration of how long <see cref="ScrollEventArgs"/> are sent after the mouse is already released.
        /// </summary>
        public int Duration { get; set; }

        public ScrollDirection ScrollDirection { get; internal set; }
    }

    [Flags]
    public enum ScrollDirection
    {
        Left = 1,
        Right = 2,
        Up = 4,
        Down = 8
    }

    /// <summary>
    /// Occurs after sending the last ScrollEventArgs.
    /// </summary>
    public class EndScrollEventArgs : HandledEventArgs
    {

    }

    public enum MouseClickType
    {
        SingleClick,
        DoubleClick
    }

    public class MouseClickEventArgs : HandledEventArgs
    {
        public Point Position { get; internal set; }
        public MouseClickType MouseClickType { get; internal set; }
    }


}
